home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
util
/
cli
/
mcomms_1_4.lha
/
Src
/
rxcontrol.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-24
|
11KB
|
370 lines
/*
** rxcontrol.c - control ARexx features
** Copyright ⌐ 1994-95 Michael Letowski
*/
#define __USE_SYSBASE
#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/rdargs.h>
#include <rexx/rxslib.h>
#include <intuition/intuition.h>
#include <workbench/startup.h>
#include <support/types.h>
#include <support/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/rexxsyslib.h>
#include "rxcontrol.rev.h"
#define DOS_NAME "dos.library"
#define DOS_VERN 37L
#define REXX_NAME "rexxsyslib.library"
#define REXX_VERN 36L
#define INT_NAME "intuition.library"
#define INT_VERN 37L
#define ICON_NAME "icon.library"
#define ICON_VERN 37L
#define RXPORT_NAME "REXX"
#define TEMPLATE "RXC=CANCEL/S,HI=HALT/S,SUSPEND/S,RESUME/S,"\
"TS=TRACESTART/S,TE=TRACEEND/S,"\
"TCO=CONOPEN/S,TCC=CONCLOSE/S,"\
"QUIET/S"
/* Options array indices (for WB arguments reading) */
#define OPT_RXC 0
#define OPT_HI 1
#define OPT_SUSPEND 2
#define OPT_RESUME 3
#define OPT_TS 4
#define OPT_TE 5
#define OPT_TCO 6
#define OPT_TCC 7
#define OPT_QUIET 8
#define OPT_COUNT 9
/* Messages */
#define MSG_UNABLE_OPEN "Unable to open '%s'\n"
#define MSG_NOT_ACTIVE "ARexx server not active\n"
#define MSG_IS_SUSPENDED "Execution is suspended\n"
#define MSG_WILL_CLOSE "RexxMaster will close\n"
#define MSG_STATUS "ARexx state:\n"\
"%sTracing is %s\n"\
"%sTrace console is %s\n%s%s%s%s"
/* Other texts */
#define MSG_OK "OK"
#define MSG_ON "ON"
#define MSG_OFF "OFF"
#define MSG_OPEN "open"
#define MSG_CLOSED "closed"
#define REQUEST_MSG " Request"
#define INFO_MSG " Information"
#define SPC_TAB " "
STATIC CONST TEXT VersionString[]=
VERSION(PROG_NAME,PROG_VERSION,PROG_REVISION,PROG_DATE);
struct Options
{
LONG opt_RXC;
LONG opt_HI;
LONG opt_Suspend;
LONG opt_Resume;
LONG opt_TS;
LONG opt_TE;
LONG opt_TCO;
LONG opt_TCC;
LONG opt_Quiet;
}; /* Options */
struct States
{
STRPTR state_Tab1; STRPTR state_Tracing;
STRPTR state_Tab2; STRPTR state_Console;
STRPTR state_Tab3; STRPTR state_Suspended;
STRPTR state_Tab4; STRPTR state_WillClose;
}; /* States */
struct Switch
{
STRPTR sw_Name;
ULONG sw_Index;
}; /* Switch */
STATIC LONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
STATIC LONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase);
STATIC LONG DoOptions(struct MsgPort *port, struct Options *opts,
struct ExecBase *SysBase, struct DosLibrary *DOSBase,
struct RxsLib *RexxSysBase);
STATIC VOID GetOptions(struct States *stat, STRPTR tab, struct RxsLib *rsb);
LONG RXControl(VOID)
{
struct ExecBase *SysBase=*((struct ExecBase **)4);
struct DosLibrary *DOSBase;
LONG RC=RETURN_FAIL;
/* Open DOS */
unless(DOSBase=(struct DosLibrary *)OpenLibrary(DOS_NAME,DOS_VERN))
throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY), NO_DOS);
RC=FromWB ? WBMode(SysBase,DOSBase) : CLIMode(SysBase,DOSBase);
/* Exceptions */
catch(NO_DOS, CloseLibrary((struct Library *)DOSBase));
return(RC);
} /* RXControl */
/* CLI mode work */
STATIC LONG CLIMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct RxsLib *RexxSysBase;
struct Options Opts;
struct States Stat;
struct RDArgs *Args;
struct MsgPort *Port;
LONG RC=RETURN_FAIL;
/* Open rexxsyslib.library */
unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
throw2(CauseIoErr(ERROR_INVALID_RESIDENT_LIBRARY,NULL), NO_REXX);
/* Read arguments */
clear(&Opts); /* Clear options buffer */
unless(Args=ReadArgs(TEMPLATE,(LONG *)&Opts,NULL))
throw2(PrintFault(IoErr(),NULL), NO_ARGS);
/* Check args */
if(Opts.opt_Suspend && Opts.opt_Resume ||
Opts.opt_TS && Opts.opt_TE || Opts.opt_TCO && Opts.opt_TCC)
throw2(CauseIoErr(ERROR_TOO_MANY_ARGS,PROG_NAME), BAD_ARGS);
/* Check for REXX port */
Forbid();
unless(Port=FindPort(RXPORT_NAME))
{
Permit();
PutStr(MSG_NOT_ACTIVE);
throw(NOT_ACTIVE);
}
RC=DoOptions(Port,&Opts,SysBase,DOSBase,RexxSysBase);
Permit();
GetOptions(&Stat,"\t",RexxSysBase);
unless(Opts.opt_Quiet)
VPrintf(MSG_STATUS,&Stat);
/* Exceptions */
catch(NOT_ACTIVE, );
catch(BAD_ARGS, );
catch(NO_ARGS, FreeArgs(Args));
catch(NO_REXX, CloseLibrary((struct Library *)RexxSysBase));
return(RC);
} /* CLIMode */
/* Workbench mode stuff */
STATIC LONG WBMode(struct ExecBase *SysBase, struct DosLibrary *DOSBase)
{
struct IntuitionBase *IntuitionBase;
struct RxsLib *RexxSysBase;
struct Library *IconBase;
STATIC CONST struct EasyStruct NoLibReq= /* No library requster */
{
sizeof(struct EasyStruct),0,
PROJ_NAME REQUEST_MSG,
MSG_UNABLE_OPEN,
MSG_OK
}; /* NoLibReq */
STATIC CONST struct EasyStruct NotActiveReq= /* No REXX requester definition */
{
sizeof(struct EasyStruct),0,
PROJ_NAME REQUEST_MSG,
MSG_NOT_ACTIVE,
MSG_OK
}; /* NotActiveReq */
STATIC CONST struct EasyStruct InfoReq= /* Informations requester */
{
sizeof(struct EasyStruct),0,
PROJ_NAME INFO_MSG,
MSG_STATUS,
MSG_OK
}; /* InfoReq */
STATIC CONST struct Switch Switches[]= /* ToolTypes switches */
{
{"CANCEL", OPT_RXC}, {"RXC", OPT_RXC},
{"HALT", OPT_HI}, {"HI", OPT_HI},
{"SUSPEND", OPT_SUSPEND},
{"RESUME", OPT_RESUME},
{"TRACESTART", OPT_TS}, {"TS", OPT_TS},
{"TRACEEND", OPT_TE}, {"TE", OPT_TE},
{"CONOPEN", OPT_TCO}, {"TCO", OPT_TCO},
{"CONCLOSE", OPT_TCC}, {"TCC", OPT_TCC},
{"QUIET", OPT_QUIET}
}; /* Switches */
struct Options Opts;
struct States Stat;
struct MsgPort *Port;
struct WBStartup *WBMsg;
struct WBArg *Args;
struct DiskObject *Object;
STRPTR *ToolArray;
BPTR OldDir;
ULONG I,J;
LONG RC=RETURN_FAIL;
WaitPort(&ThisProcessS->pr_MsgPort);
WBMsg=(struct WBStartup *)GetMsg(&ThisProcessS->pr_MsgPort);
/* Open libraries */
unless(IntuitionBase=(struct IntuitionBase *)OpenLibrary(INT_NAME,INT_VERN))
throw2(SetResult2(ERROR_INVALID_RESIDENT_LIBRARY), NO_INT);
unless(IconBase=OpenLibrary(ICON_NAME,ICON_VERN))
throw2(EasyRequest(NULL,&NoLibReq,NULL,ICON_NAME), NO_ICON);
unless(RexxSysBase=(struct RxsLib *)OpenLibrary(REXX_NAME,REXX_VERN))
throw2(EasyRequest(NULL,&NoLibReq,NULL,REXX_NAME), NO_REXX);
/* Read arguments */
clear(&Opts); /* Clear options buffer */
for(I=0, Args=WBMsg->sm_ArgList; I<WBMsg->sm_NumArgs; I++, Args++)
if(Args->wa_Lock) /* Lock exists */
{
OldDir=CurrentDir(Args->wa_Lock); /* CD to icon directory */
if(Args->wa_Name && (Object=GetDiskObject(Args->wa_Name)))
{
ToolArray=(STRPTR *)Object->do_ToolTypes;
for(J=0; J<elems(Switches); J++)
if(FindToolType(ToolArray,Switches[J].sw_Name))
((LONG *)&Opts)[Switches[J].sw_Index]=TRUE;
FreeDiskObject(Object);
}
CurrentDir(OldDir); /* CD back */
}
/* Check args */
if(Opts.opt_Suspend && Opts.opt_Resume ||
Opts.opt_TS && Opts.opt_TE || Opts.opt_TCO && Opts.opt_TCC)
throw2(SetIoErr(ERROR_TOO_MANY_ARGS), BAD_ARGS);
/* Check for REXX port */
Forbid(); /* Make sure a port doesn't disappear */
unless(Port=FindPort(RXPORT_NAME))
{
Permit();
EasyRequestArgs(NULL,&NotActiveReq,NULL,NULL);
throw(NOT_ACTIVE);
}
RC=DoOptions(Port,&Opts,SysBase,DOSBase,RexxSysBase);
Permit(); /* We are done */
GetOptions(&Stat,SPC_TAB,RexxSysBase);
unless(Opts.opt_Quiet)
EasyRequestArgs(NULL,&InfoReq,NULL,&Stat);
/* Exceptions */
catch(NOT_ACTIVE, );
catch(BAD_ARGS, );
catch(NO_REXX, CloseLibrary((struct Library *)RexxSysBase));
catch(NO_ICON, CloseLibrary(IconBase));
catch(NO_INT, CloseLibrary((struct Library *)IntuitionBase));
ReplyMsg((struct Message *)WBMsg); /* Reply to Workbench message */
return(RC);
} /* WBMode */
STATIC LONG DoOptions(struct MsgPort *port, struct Options *opts,
struct ExecBase *SysBase, struct DosLibrary *DOSBase,
struct RxsLib *RexxSysBase)
{
struct RexxMsg *RXMsg;
LONG RC=RETURN_OK; /* Everything looks OK so far */
/* RXC */
if(opts->opt_RXC) /* Shut down REXX */
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL)) /* Create message */
{
RXMsg->rm_Action=RXCLOSE | RXFF_NONRET; /* Set action */
PutMsg(port,(struct Message *)RXMsg); /* Send message */
}
else /* No message */
{
SetIoErr(ERROR_NO_FREE_STORE); /* Set error code */
RC=RETURN_ERROR; /* And mark it */
}
/* HI */
if(opts->opt_HI) /* Interrupt tasks */
{
bset(RexxSysBase->rl_Flags,RLFB_HALT); /* Set interrupt request */
Signal(port->mp_SigTask,flag(port->mp_SigBit));
}
/* Suspend/Resume */
if(opts->opt_Suspend) /* Suspension requested */
{
bset(RexxSysBase->rl_Flags,RLFB_SUSP); /* Set suspension request */
Signal(port->mp_SigTask,flag(port->mp_SigBit));
}
if(opts->opt_Resume) /* Resumption requested */
{
bclr(RexxSysBase->rl_Flags,RLFB_SUSP); /* Set reumption request */
Signal(port->mp_SigTask,flag(port->mp_SigBit));
}
/* TE/TS */ /* Tracing enable/disable */
if(opts->opt_TE) bclr(RexxSysBase->rl_Flags,RLFB_TRACE);
if(opts->opt_TS) bset(RexxSysBase->rl_Flags,RLFB_TRACE);
/* TCO/TCC */
if(opts->opt_TCO) /* Open console */
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL)) /* Create message */
{
RXMsg->rm_Action=RXTCOPN | RXFF_NONRET; /* Set open message */
PutMsg(port,(struct Message *)RXMsg); /* Send message */
}
else /* No message */
{
SetIoErr(ERROR_NO_FREE_STORE); /* Set error code */
RC=RETURN_ERROR; /* Mark error */
}
if(opts->opt_TCC) /* Close console */
if(RXMsg=CreateRexxMsg(NULL,NULL,NULL)) /* Create message */
{
RXMsg->rm_Action=RXTCCLS | RXFF_NONRET; /* Set open message */
PutMsg(port,(struct Message *)RXMsg); /* Send message */
}
else /* No message */
{
SetIoErr(ERROR_NO_FREE_STORE); /* Set error code */
RC=RETURN_ERROR; /* Mark error */
}
return(RC);
} /* DoOptions */
STATIC VOID GetOptions(struct States *stat, STRPTR tab, struct RxsLib *rsb)
{
clear(stat); /* Set defaults */
stat->state_Tab1=stat->state_Tab2=tab;
stat->state_Tracing=btst(rsb->rl_Flags,RLFB_TRACE) ? MSG_ON : MSG_OFF;
stat->state_Console=rsb->rl_TraceFH ? MSG_OPEN : MSG_CLOSED;
if(btst(rsb->rl_Flags,RLFB_SUSP))
{
stat->state_Suspended=MSG_IS_SUSPENDED;
stat->state_Tab3=tab;
}
if(btst(rsb->rl_Flags,RLFB_CLOSE))
{
stat->state_WillClose=MSG_WILL_CLOSE;
stat->state_Tab4=tab;
}
} /* GetOptions */